// 第一个参数传入null 在非严格模式下代表使用默认this指向
// 第二个参数可以是数组或是带下标的类数组(arguments) 传入原函数并且调用
console.log(Math.max.apply(null, [1, 2, 3, 4, 5]))

// 模拟简化版Function.prototype.bind
// Function.prototype.bind = function (context) {
//     // 保存原函数
//     var self = this
//     return function () { // 返回一个新的函数
//         // 执行新函数时 会把之前传入的context当做新函数体内的this
//         return self.apply(context, arguments)
//     }
// }

// 模拟预传参版Function.prototype.bind
Function.prototype.bind = function () {
    var self = this, // 保存原函数
        context = [].shift.call(arguments), // 需要绑定的this上下文
        args = [].slice.call(arguments) // 剩余的参数转出数组
    return function () { // 返回一个新的函数
        // 执行新的函数的时候 会把之前传入的context当做新函数体内的this
        // 并且组合两次分别传入的参数 作为新函数的参数
        return self.apply(context, [].concat.call(args, [].slice.call(arguments)))
    }

}


var obj = { name: "Amadeus" }
var func = function (a, b, c, d) {
    console.log(this.name)
    console.log([a, b, c, d])
}.bind(obj, 1, 2)

func(3, 4)

var func2 = function (a, b, c, d) {
    console.log(this.name)
    console.log([a, b, c, d])
}.bind(obj)

func2(1,2)

// 借用其他对象的方法
var func3 = function () {
    // 借用数组的方法 push一个新的元素
    Array.prototype.push.call(arguments,3)
    console.log(arguments)
}
func3(1,2)
